package com.wealth.trade.web.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alipay.config.AlipayConfig;
import com.alipay.util.AlipayNotify;
import com.alipay.util.AlipaySubmit;
import com.wealth.member.service.IMembershipService;
import com.wealth.order.entity.Order;
import com.wealth.order.entity.OrderPlat;
import com.wealth.order.enums.PayStatusEnum;
import com.wealth.order.service.IOrderPlatService;
import com.wealth.payment.entity.PaymentAccount;
import com.wealth.payment.enums.PaymentTypeEnum;
import com.wealth.payment.service.IPaymentAccountService;
import com.wealth.platform.entity.SldConfig;
import com.wealth.platform.enums.SldConfigTypeEnum;
import com.wealth.platform.service.ISldConfigService;
import com.wealth.system.service.InitService;
import com.wealth.system.web.controller.BaseController;
import com.wealth.wechat.service.WechatConfigService;
import com.wealth.wechat.service.WechatPayService;

import iaas.enums.YesOrNoEnum;


/**
 * 支付宝扫码支付
 * @author chan
 * 
 * step1.订单创建成功,
 * step2 跳转支付页面 alipay/{orderid}
 * step3.同步返回  alipay/return_url/{orderid}
 * step4.异步返回  alipay/notify_url/{orderid}
 * Tips
 * 1.异步通知 必须配置外网访问
 * 2.同步通知,异步通知,获得参数 如果tomcat对乱码做过处理,获得params不需要编码处理
 * 3.同步通知,异步通知,获得验证结果
 *   统一调用  AlipayNotify.verifyNotify(params,payaccount.getPartnerid(),payaccount.getPayservice())
 * 4.生成签名结果 
 *   AlipayNotify.getSignVeryfy(params, sign, isSort,corpkey)
 *   isSort,true/false分别适用于电脑端/手机端
 */
@SuppressWarnings(value="all")
@Controller
@RequestMapping(value="/alipay")
public class AlipayController extends BaseController {
	 
		Logger logger = Logger.getLogger(AlipayController.class);
	 
		public static final String ALIPAY_GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
		
		@Autowired
		private ISldConfigService sldConfigService;
		@Autowired
		private IPaymentAccountService accountService;
		@Autowired
		private IOrderPlatService orderPlatService;
		
		public String Alipay_URL = "";
		
		@ModelAttribute
		public void init() throws Exception{
			SldConfig config = sldConfigService.getSldConfigByCorpIdAndType(corpid, SldConfigTypeEnum.PC.getValue());
			Alipay_URL = config.getDomain();
		}
		
		/** 
		 * 功能 : 前往支付宝支付页面
		 * 说明 : 订单创建后,生成支付链接,跳转到支付宝页面
		 * create by chan on 2015-09-10
		 */
		@RequestMapping(value="/{orderid}")
		public String payForm(Model model,@PathVariable Long orderid) throws Exception{
			//支付账号
			PaymentAccount payaccount = accountService.findByCorpIdAndPaymode(corpid, PaymentTypeEnum.ALIPAY.getValue());
			OrderPlat orderPlat = orderPlatService.get(orderid);
			orderPlat.setPaymentType(PaymentTypeEnum.ALIPAY.getValue());
			orderPlatService.save(orderPlat);
			
			String sHtmlText = buildRequest(orderPlat, payaccount);
			model.addAttribute("sHtmlText", sHtmlText);
			return "/alipay/pay"; 	
		}

		
	    /**
	     *功能：即时到账交易接口接入页
	     *版本：3.3
	     *日期：2012-08-14
	     *说明：
	     *以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
	     *该代码仅供学习和研究支付宝接口使用，只是提供一个参考。

	     *************************注意*****************
	     *如果您在接口集成过程中遇到问题，可以按照下面的途径来解决
	     *1、商户服务中心（https://b.alipay.com/support/helperApply.htm?action=consultationApply），提交申请集成协助，我们会有专业的技术工程师主动联系您协助解决
	     *2、商户帮助中心（http://help.alipay.com/support/232511-16307/0-16307.htm?sh=Y&info_type=9）
	     *3、支付宝论坛（http://club.alipay.com/read-htm-tid-8681712.html）
	     *如果不想使用扩展功能请把扩展功能参数赋空值。
	     **********************************************
	     */
	    private String buildRequest(OrderPlat orderPlat,PaymentAccount payaccount) throws Exception { 
	    		
	        // 支付类型  
	        // 必填，不能修改  
	        String payment_type = "1";  
	        // 服务器异步通知页面路径  
	        // 需http://格式的完整路径，不能加?id=123这类自定义参数  
	        String notify_url =  Alipay_URL+"/alipay/notify_url/"+orderPlat.getId();
	        // 页面跳转同步通知页面路径  
	        // 需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/  
	        String return_url = Alipay_URL+"/alipay/return_url/"+orderPlat.getId();
	        //商户订单号.商户网站订单系统中唯一订单号，必填  
	        String out_trade_no = orderPlat.getOrderno() ;
	        //订单名称   必填   
	        String subject = "商城订单支付";  
	        //订单金额
	        String total_fee = orderPlat.getTotal().toString();
	        //订单描述
	        String body = "订单描述,共"+total_fee+"元";
	         
	        Map<String, String> sParaTemp = new HashMap<String, String>();
	        sParaTemp.put("service", "create_direct_pay_by_user");//接口服务----即时到账
	        sParaTemp.put("partner", payaccount.getPartnerid());//支付宝PID
	        sParaTemp.put("seller_email", payaccount.getSellerid());//卖家支付宝账号
	        sParaTemp.put("_input_charset", AlipayConfig.input_charset);//统一编码
	        sParaTemp.put("payment_type", payment_type);//支付类型
	        sParaTemp.put("notify_url", notify_url);//异步通知页面
	        sParaTemp.put("return_url", return_url);//页面跳转同步通知页面
	        sParaTemp.put("out_trade_no", out_trade_no);//商品订单编号
	        sParaTemp.put("subject", subject);//商品名称
	        sParaTemp.put("total_fee", total_fee);//价格
	        sParaTemp.put("body", body);
	          
	        //建立请求
	    	String sHtmlText = AlipaySubmit.buildRequest(ALIPAY_GATEWAY_NEW, sParaTemp, "get", "确认",payaccount.getPayservice());
	        logger.info("生成链接"+sHtmlText);
            return sHtmlText;
	    }  
	    
	    
	    
	    /** 
		 * 功能：异步通知
		 * 说明 : 根据支付宝返回的业务结果，商户判断是否调用支付方法
		 * create  by chan on 2015-09-23
		 */
		@RequestMapping(value="/notify_url/{orderid}",method=RequestMethod.POST)
		public void notify(@PathVariable Long orderid,HttpServletRequest request,HttpServletResponse response) throws Exception
		{
			System.out.println("=============================alipay start notify..."+new Date());
			//支付账号
			PaymentAccount account = accountService.findByCorpIdAndPaymode(corpid, PaymentTypeEnum.ALIPAY.getValue());
			if(null == account){
				System.out.println("=============================商家没有设置支付账号...");
				logger.info("商家没有设置支付账号");
			}else{
				//获取支付宝POST过来反馈信息
				Map<String,String> params = new HashMap<String,String>();
				Map requestParams = request.getParameterMap();
				for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
					String name = (String) iter.next();
					String[] values = (String[]) requestParams.get(name);
					String valueStr = "";
					for (int i = 0; i < values.length; i++) {
						valueStr = (i == values.length - 1) ? valueStr + values[i]
								: valueStr + values[i] + ",";
					}
					//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
					//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
					params.put(name, valueStr);
				}
		
				//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
				//RSA签名解密
			   	if(AlipayConfig.sign_type.equals("0001")) {
			   		params = AlipayNotify.decrypt(params);
			   	}
			   	//System.out.println("支付宝支付服务器异步通知页面路径:"+params);

			   	//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
				//商户订单号
				String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
				//支付宝交易号
				String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
				//交易状态
				String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
				//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
				String msg="";
				if(AlipayNotify.verifyNotify(params,account.getPartnerid(),account.getPayservice())){//验证成功
					//////////////////////////////////////////////////////////////////////////////////////////
					//请在这里加上商户的业务逻辑程序代码
					//——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
					if(trade_status.equals("TRADE_FINISHED")){
						//判断该笔订单是否在商户网站中已经做过处理
							//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
							//如果有做过处理，不执行商户的业务程序
						//注意：
						//该种交易状态只在两种情况下出现
						//1、开通了普通即时到账，买家付款成功后。
						//2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。
						msg="success";	
						//请不要修改或删除
					} else if (trade_status.equals("TRADE_SUCCESS")){
						//判断该笔订单是否在商户网站中已经做过处理
							//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
							//如果有做过处理，不执行商户的业务程序
						//注意：
						//该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。
						msg="success";	
					}
					//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
					//////////////////////////////////////////////////////////////////////////////////////////
				}else{//验证失败
					msg="fail";	
				}
				
				//支付宝支付成功
				if(msg.equals("success")){
					//查询订单
					OrderPlat orderPlat = orderPlatService.get(orderid);
					if(null!=orderPlat && orderPlat.getPaystatus()==YesOrNoEnum.NO.getValue()){
						orderPlatService.payOrder(orderPlat);
					}
					//请不要修改或删除
					response.getWriter().println("success");
				}else{
					response.getWriter().println("fail");
				}
				
				System.out.println("支付宝支付 服务器异步通知页面路径:"+params);
				System.out.println("支付宝支付 页面跳转异步通知页面路径:"+msg);
			}
		}
		
		/** 
		 * 功能 : 同步通知
		 * 说明 : 根据支付宝返回的业务结果，商户判断是否调用支付方法
		 * create by  2015-09-23 by chan
		 */
		@RequestMapping(value="/return_url/{orderid}")
		public String syncNotify(Model model,@PathVariable Long orderid,HttpServletRequest request)throws Exception{
				
			//支付账号
			PaymentAccount account = accountService.findByCorpIdAndPaymode(corpid, PaymentTypeEnum.ALIPAY.getValue());
			if(null == account){
				logger.info("商家没有设置支付账号");
				return "/system/500";
			}else{
				//获取支付宝GET过来反馈信息
				Map<String,String> params = new HashMap<String,String>();
				Map requestParams = request.getParameterMap();
				System.out.println("请求参数:"+requestParams);
				for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
					String name = (String) iter.next();
					String[] values = (String[]) requestParams.get(name);
					String valueStr = "";
					for (int i = 0; i < values.length; i++) {
						valueStr = (i == values.length - 1) ? valueStr + values[i]
								: valueStr + values[i] + ",";
					}
					//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
					//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
					params.put(name, valueStr);
				}
				System.out.println("支付参数:"+params);
		
			   	System.out.println("支付宝支付 服务器同步通知页面路径:"+params);
			   	
				//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
				//商户订单号	String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
				//支付宝交易号	String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
				//交易状态
			   	//String result = new String(request.getParameter("result").getBytes("ISO-8859-1"),"UTF-8");
		
				//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
				
				//计算得出通知验证结果
				boolean verify_result = AlipayNotify.verifyNotify(params,account.getPartnerid(),account.getPayservice());
				
				String msg="";
				if(verify_result){//验证成功
					//////////////////////////////////////////////////////////////////////////////////////////
					//请在这里加上商户的业务逻辑程序代码
		
					//——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
					//该页面可做页面美工编辑
					msg="验证成功<br />";
					//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——	
					//查询订单
					OrderPlat orderPlat = orderPlatService.get(orderid);
					if(null!=orderPlat && orderPlat.getPaystatus()==YesOrNoEnum.NO.getValue()){
						orderPlatService.payOrder(orderPlat);
					}
					return "redirect:/manage/myCenter/myOrder?type=3";
				}else{
					//该页面可做页面美工编辑
					msg="验证失败";
				}
				
				//支付宝支付 服务器异步通知页面路径
				model.addAttribute("errormsg", "支付宝支付 服务器同步通知页面路径:"+msg);
				return "/system/500";
			}
		}
		
		
//		/** 2014-10-13  add by wayne
//		 * 支付宝支付 操作中断返回地址
//		 * @param model
//		 * @param request
//		 * @return
//		 * @throws Exception
//		 */
//		@RequestMapping(value="/error_url/{orderid}")
//		public String alipayerror(ModelMap model,@PathVariable java.lang.Long orderid,HttpServletRequest request) throws Exception{
//				
//			System.out.println("支付宝支付操作中断返回地址:"+orderid);
//			Order order=orderService.getOrder(orderid);
//			if(null!=order){
//				model.addAttribute("errormsg", "订单支付错误");
//				return "redirect:"+Alipay_URL+"/manage/order/"+order.getId();
//			}else{
//				return "/system/500";
//			}
//		}

}


